package com.tomato.dynamic.threadpool.core.monitor;

import com.tomato.dynamic.threadpool.common.config.DynamicThreadPoolProperties;
import com.tomato.dynamic.threadpool.common.queue.BlockingQueueInfo;
import com.tomato.dynamic.threadpool.common.queue.ThreadPoolInfo;
import com.tomato.dynamic.threadpool.core.manage.GlobalThreadPoolManage;
import com.tomato.dynamic.threadpool.core.support.BlockingQueueInfoBuilder;
import com.tomato.dynamic.threadpool.core.support.ThreadFactoryBuilder;
import com.tomato.dynamic.threadpool.core.support.ThreadPoolInfoBuilder;
import com.tomato.dynamic.threadpool.core.thread.DynamicThreadPoolExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;

import javax.annotation.Resource;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池监控器
 *
 * @author lizhifu
 * @date 2022/4/11
 */
@Slf4j
public class DynamicThreadPoolMonitor implements ApplicationRunner, Ordered {
    @Resource
    private DynamicThreadPoolProperties dynamicThreadPoolProperties;
    /**
     * 监控线程池
     */
    private static final ScheduledExecutorService MONITOR_EXECUTOR = new ScheduledThreadPoolExecutor(
            1,
            ThreadFactoryBuilder.newBuilder().daemon(true).prefix("dynamic-thread-pool-monitor").build());

    @Override
    public void run(ApplicationArguments args) throws Exception {
        MONITOR_EXECUTOR.scheduleWithFixedDelay(this::run,
                0, dynamicThreadPoolProperties.getMonitorInterval(), TimeUnit.SECONDS);
    }
    private void run() {
        GlobalThreadPoolManage.list().forEach(threadPool -> {
            DynamicThreadPoolExecutor threadPoolExecutor = GlobalThreadPoolManage.getExecutorService(threadPool);

            ThreadPoolInfo threadPoolInfo = ThreadPoolInfoBuilder.newBuilder(threadPoolExecutor).build();
            BlockingQueueInfo blockingQueueInfo = BlockingQueueInfoBuilder.newBuilder(threadPoolExecutor).build();

            log.info("{} 线程池 threadPoolInfo:{}，blockingQueueInfo:{}",threadPool,threadPoolInfo,blockingQueueInfo);
        });
    }
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }
}
